package main

import (
    "encoding/json"
    "fmt"

    "github.com/hyperledger/fabric-chaincode-go/shim"
    pb "github.com/hyperledger/fabric-protos-go/peer"
)

// Asset 定义资产结构
type Asset struct {
    ID          string `json:"id"`
    Name        string `json:"name"`
    Info        string `json:"info"`
    Owner       string `json:"owner"`
}

// SmartContract 定义智能合约结构
type SmartContract struct {
}

// Init 链码初始化方法
func (s *SmartContract) Init(stub shim.ChaincodeStubInterface) pb.Response {
    return shim.Success(nil)
}

// Invoke 链码调用方法
func (s *SmartContract) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
    fn, args := stub.GetFunctionAndParameters()
    var result []byte
    var err error
    if fn == "CreateAsset" {
        result, err = s.CreateAsset(stub, args)
    } else if fn == "TransferAsset" {
        result, err = s.TransferAsset(stub, args)
    } else {
        return shim.Error("不支持的函数调用")
    }
    if err != nil {
        return shim.Error(err.Error())
    }
    return shim.Success(result)
}

// CreateAsset 创建资产的方法
func (s *SmartContract) CreateAsset(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
    if len(args) != 4 {
        return nil, fmt.Errorf("需要提供 4 个参数：资产编号、资产名、资产信息、资产所有者")
    }
    asset := Asset{
        ID:          args[0],
        Name:        args[1],
        Info:        args[2],
        Owner:       args[3],
    }
    assetJSON, err := json.Marshal(asset)
    if err != nil {
        return nil, err
    }
    err = stub.PutState(asset.ID, assetJSON)
    if err != nil {
        return nil, err
    }
    return assetJSON, nil
}

// TransferAsset 转移资产的方法
func (s *SmartContract) TransferAsset(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
    if len(args) != 2 {
        return nil, fmt.Errorf("需要提供 2 个参数：资产编号、新的资产所有者")
    }
    assetID := args[0]
    newOwner := args[1]

    assetJSON, err := stub.GetState(assetID)
    if err != nil {
        return nil, fmt.Errorf("获取资产信息时出错: %v", err)
    }
    if assetJSON == nil {
        return nil, fmt.Errorf("资产 %s 不存在", assetID)
    }

    var asset Asset
    err = json.Unmarshal(assetJSON, &asset)
    if err != nil {
        return nil, err
    }

    asset.Owner = newOwner
    updatedAssetJSON, err := json.Marshal(asset)
    if err != nil {
        return nil, err
    }
    err = stub.PutState(asset.ID, updatedAssetJSON)
    if err != nil {
        return nil, err
    }
    return updatedAssetJSON, nil
}    